package com.niiwoo.civet.trade.service.dubbo.contract;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.dto.common.BankCardDTO;
import com.niiwoo.civet.account.dto.common.BankTypeDTO;
import com.niiwoo.civet.account.service.bankcard.BankCardDubboService;
import com.niiwoo.civet.base.enums.BorrowProjectTypeEnum;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.mapper.ProjectMapperExt;
import com.niiwoo.civet.trade.enums.BorrowerTypeEnum;
import com.niiwoo.civet.trade.service.contract.WithholdContractDubboService;
import com.niiwoo.civet.trade.service.local.contract.ContractBaseService;
import com.niiwoo.civet.trade.service.local.contract.WithholdContractService;
import com.niiwoo.civet.user.dto.request.DataStatusRequestDTO;
import com.niiwoo.civet.user.dto.response.UserAuthorizationInfoResponseDTO;
import com.niiwoo.civet.user.dto.response.UserBasicInfoResponseDTO;
import com.niiwoo.civet.user.dto.response.UserIdentityInfoResponseDTO;
import com.niiwoo.civet.user.enums.UserDataStatusEnum;
import com.niiwoo.civet.user.enums.UserDataTypeEnum;
import com.niiwoo.civet.user.service.UserAuthorizationInfoDubboService;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserIdentityDubboService;
import com.niiwoo.civet.user.service.UserStatusDubboService;
import com.niiwoo.tripod.fadada.FadadaService;
import com.niiwoo.tripod.fadada.dto.request.ExtSignRequestDTO;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO;
import com.niiwoo.tripod.fadada.dto.response.FadadaResponseDTO;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: wuke
 * @Description:
 * @Date: Created in 21:25 2017/12/13
 */
@Slf4j
@Service(version = "1.0.0")
public class WithholdContractDubboServiceImpl implements WithholdContractDubboService {
    @Autowired
    private WithholdContractService withholdContractService;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private FadadaService fadadaService;
    @Reference(version = "1.0.0")
    private UserIdentityDubboService userIdentityDubboService;
    @Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;
    @Reference(version = "1.0.0")
    private UserStatusDubboService userStatusDubboService;
    @Reference(version = "1.0.0")
    private UserAuthorizationInfoDubboService userAuthorizationInfoDubboService;
    @Reference(version = "1.0.0")
    private BankCardDubboService bankCardDubboService;

    @Autowired
    private ProjectMapperExt projectMapperExt;
    @Autowired
    private ContractBaseService contractBaseService;

    @Override
    public void contractGenerateAndSign(String userId, Long projectId) throws Exception {
        log.info("contractGenerateAndSign.userId={} start",userId);

        Project project = projectMapperExt.selectByPrimaryKey(projectId);
        if((BorrowProjectTypeEnum.ORG_SPEEDLOAN_NEW.getValue().equals(project.getType())
                || BorrowProjectTypeEnum.DECORATION_LOAN.getValue().equals(project.getType()))
                && BorrowerTypeEnum.COMPANY.getType().equals(project.getBorrowerType())){
            // 企业代扣
            withholdContractService.companyWithhold(project, userId);
        }else {

            //获取合同模板
            String contractTemplateId = withholdContractService.getContractTemplateId();
            //获取合同内容
            Map<String, String> contractContent = this.contractContentInit(userId, projectId, contractTemplateId);
            log.info("contractGenerateAndSign.userId={},contractContent={}", userId, JSON.toJSONString(contractContent));
            //生成合同
            boolean isContractGenerateSuccess = this.contractGenerate(userId, contractTemplateId, contractContent);
            if (!isContractGenerateSuccess) {
                log.info("contractGenerateAndSign.userId={} 合同生成失败", userId);
                return;
            }
            //合同盖章
            this.contractSign(userId, projectId, contractTemplateId, contractContent);
        }
    }

    @Override
    public void kaolaContractGenerateAndSign(String userId, Long projectId){
        log.info("kaolaContractGenerateAndSign.userId={} start",userId);

        //获取合同模板
        String contractTemplateId = withholdContractService.getKaolaWithholdContractTemplateId();
        //获取合同内容
        Map<String, String> contractContent = this.kaolaContractContentInit(userId,projectId,contractTemplateId);
        log.info("contractGenerateAndSign.userId={},contractContent={}",userId,JSON.toJSONString(contractContent));
        //生成合同
        boolean isContractGenerateSuccess = this.contractGenerate(userId,contractTemplateId,contractContent);
        if(!isContractGenerateSuccess){
            log.info("contractGenerateAndSign.userId={} 合同生成失败",userId);
            return;
        }
        //合同盖章
        this.contractSign(userId,projectId,contractTemplateId,contractContent);
    }

    /**
     * 考拉理财用户还款代扣合同统一签署
     * @param userIdList
     * @param status
     * @param channelCode
     */
    @Override
    public String withholdContractSign(List<String> userIdList, byte status, String channelCode){
        log.info("withholdContractSign.userId={} start",userIdList.toArray());
        List<Project> projectList=withholdContractService.queryUserSignConstract(userIdList,status,channelCode);
        if(projectList!=null){
            for(Project project:projectList){
                try {
                    kaolaContractGenerateAndSign(project.getBorrowUserId(),project.getProjectId());
                    log.info("withholdContractSign.contractGenerateAndSign success,userId={}",project.getBorrowUserId());
                } catch (BizException e) {
                    log.error("withholdContractSign BizException,userId={}", project.getBorrowUserId(),e);
                    return FadadaResponseDTO.RESULT_ERROR;
                } catch (Exception e) {
                    log.error("withholdContractSign Exception,userId={}", project.getBorrowUserId(),e);
                    return FadadaResponseDTO.RESULT_ERROR;
                }
            }
        }
        log.info("withholdContractSign.userId={} end",projectList.size());
        return FadadaResponseDTO.RESULT_SUCCESS;
    }

    /**
     * 合同内容初始化
     * @return
     */
    public Map<String,String> contractContentInit(String userId,Long projectId,String contractTemplateId){
        UserIdentityInfoResponseDTO userIdentityInfoResponseDTO = userIdentityDubboService.get(userId);
        UserBasicInfoResponseDTO userBasicInfo = userBasicInfoDubboService.getUserBasicInfo(userId);
        String idCard = userIdentityInfoResponseDTO.getIdCard();//身份证号
        String name = userIdentityInfoResponseDTO.getName();//姓名
        String mobileNo = userBasicInfo.getMobileNo();//手机号
        String holdName="深圳市你我金融信息服务有限公司";//受托人
        String domainName = "www.niiwoo.com";//域名
        String platformName = "你我金融"; //平台名
        String sinDate= FastDateFormat.getInstance("yyyy年MM月dd日").format(new Date()); //签署日期
        String contractNo = String.valueOf(snowflakeIdWorker.nextId());

        Map<String,String> contractContentMap = new HashMap<>();
        contractContentMap.put("userId",userId);
        contractContentMap.put("idCard",idCard);
        contractContentMap.put("name",name);
        contractContentMap.put("mobileNo",mobileNo);
        contractContentMap.put("holdName",holdName);
        contractContentMap.put("domainName",domainName);
        contractContentMap.put("platformName",platformName);
        contractContentMap.put("contractNo",contractNo);
        contractContentMap.put("finalSinName",contractBaseService.getFinalSinNameWithSpace(name));
        contractContentMap.put("signDate",sinDate);

        withholdContractService.contractInfoSave(userId,projectId,contractTemplateId,contractNo);
        return contractContentMap;
    }
    /**
     * 考拉用户代扣合同内容初始化
     * @return
     */
    public Map<String,String> kaolaContractContentInit(String userId,Long projectId,String contractTemplateId){
        UserIdentityInfoResponseDTO userIdentityInfoResponseDTO = userIdentityDubboService.get(userId);
        UserBasicInfoResponseDTO userBasicInfo = userBasicInfoDubboService.getUserBasicInfo(userId);
        BankCardDTO bankCardDTO=bankCardDubboService.getUserBankCardInfo(userId);
        String idCard = userIdentityInfoResponseDTO.getIdCard();//身份证号
        String name = userIdentityInfoResponseDTO.getName();//姓名
        String mobileNo = userBasicInfo.getMobileNo();//手机号
        String holdName="国隆达非融资性担保（深圳）有限公司";//受托人
        String domainName = "www.kaolalicai.cn";//域名
        String platformName = "考拉理财"; //平台名
        String sinDate= FastDateFormat.getInstance("yyyy年MM月dd日").format(new Date()); //签署日期
        String contractNo = String.valueOf(snowflakeIdWorker.nextId());
        String bankAccountNo=bankCardDTO.getBankAccountNo();
        BankTypeDTO  bankTypeDTO=bankCardDTO.getBankType();
        String bankName=bankTypeDTO.getBankName();

        Map<String,String> contractContentMap = new HashMap<>();
        contractContentMap.put("userId",userId);
        contractContentMap.put("idCard",idCard);
        contractContentMap.put("name",name);
        contractContentMap.put("mobileNo",mobileNo);
        contractContentMap.put("holdName",holdName);
        contractContentMap.put("domainName",domainName);
        contractContentMap.put("platformName",platformName);
        contractContentMap.put("contractNo",contractNo);
        contractContentMap.put("finalSinName",contractBaseService.getFinalSinNameWithSpace(name));
        contractContentMap.put("sinDate",sinDate);
        contractContentMap.put("bankName",bankName);
        contractContentMap.put("bankAccountNo",bankAccountNo);

        withholdContractService.kaolaContractInfoSave(userId,projectId,contractTemplateId,contractNo);
        return contractContentMap;
    }
    public boolean contractGenerate(String userId,String TemplateId,Map<String, String> contractContent){
        log.info("contractGenerate.userId={} start",userId);
        String contractNo = contractContent.get("contractNo");

        GenerateContractRequestDTO generateContractRequestDTO = new GenerateContractRequestDTO();
        generateContractRequestDTO.setContractId(contractNo);
        generateContractRequestDTO.setDocTitle("还款服务委托书");
        generateContractRequestDTO.setTemplateId(TemplateId);
        //generateContractRequestDTO.setDynamicTables(tables);
        generateContractRequestDTO.setParameterMap(contractContent);
        FadadaResponseDTO fadadaResponseDTO = null;
        try {
            log.info("contractGenerate.userId={},generateContractRequestDTO={}",userId,JSON.toJSONString(generateContractRequestDTO));
            fadadaResponseDTO = fadadaService.generateContract(generateContractRequestDTO).get();
            log.info("contractGenerate.userId={},fadadaResponseDTO={}",userId,JSON.toJSONString(fadadaResponseDTO));
        } catch (Exception e) {
            log.error("contractGenerate.userId={} 合同生成异常",userId,e);
            return false;
        }

        if(fadadaResponseDTO!=null
                && FadadaResponseDTO.RESULT_SUCCESS.equals(fadadaResponseDTO.getResult())
                && "1000".equals(fadadaResponseDTO.getCode())){
            log.info("contractGenerate.userId={} 合同生成成功",userId);
            return true;
        }
        log.info("contractGenerate.userId={} 合同生成失败",userId);
        return false;
    }

    public void contractSign(String userId,Long projectId,String contractTemplateId,Map<String, String> contractContent){
        log.info("contractSign.userId={} start",userId);
        String contractNo = contractContent.get("contractNo");
        String finalSinName = contractContent.get("finalSinName");
        UserAuthorizationInfoResponseDTO userAuthorizationInfo = userAuthorizationInfoDubboService.getUserAuthorizationInfo(userId);
        log.info("contractSign.userId={},userAuthorizationInfo={}",userId,JSON.toJSONString(userAuthorizationInfo));

        ExtSignRequestDTO paramBean = new ExtSignRequestDTO();
        paramBean.setTransactionId(contractNo);
        paramBean.setContractId(contractNo);
        paramBean.setClientRole("4");
        paramBean.setCustomerId(userAuthorizationInfo.getFadadaCacertId());
        paramBean.setDocTitle(finalSinName + "的还款服务委托书");
        paramBean.setSignKeyword(finalSinName);
        try {
            log.info("contractSign.userId={},paramBean={}",userId,JSON.toJSONString(paramBean));
            FadadaResponseDTO fadadaResponseDTO = fadadaService.extSignAuto(paramBean).get();
            log.info("contractSign.userId={},fadadaResponseDTO={}",userId,JSON.toJSONString(fadadaResponseDTO));

            if(this.isContractSignSuccess(fadadaResponseDTO)){
                log.info("contractSign.userId={},success合同盖章成功",userId);
                withholdContractService.contractSignSuccessDataDeal(userId,contractNo,fadadaResponseDTO.getDownloadUrl(),fadadaResponseDTO.getViewUrl());
            }else {
                log.info("contractSign.userId={},fail合同盖章失败",userId);
                updateDataStatus(userId,UserDataStatusEnum.WithholdContractSignStatus.FAIL_SIGN);
            }
        } catch (Exception e) {
            log.info("contractSign.userId={},error合同盖章异常",userId,e);
            updateDataStatus(userId,UserDataStatusEnum.WithholdContractSignStatus.FAIL_SIGN);
        }
    }

    //判断合同签章是否成功
    private boolean isContractSignSuccess(FadadaResponseDTO fadadaResponseDTO){
        if(fadadaResponseDTO!=null
                && FadadaResponseDTO.RESULT_SUCCESS.equals(fadadaResponseDTO.getResult())
                && "1000".equals(fadadaResponseDTO.getCode())){
            return true;
        }
        return false;
    }

    public void updateDataStatus(String userId,UserDataStatusEnum.WithholdContractSignStatus dataStatusEnum){
        Date now = new Date();
        DataStatusRequestDTO dataStatusDTO = new DataStatusRequestDTO();
        dataStatusDTO.setUserId(userId);
        dataStatusDTO.setDataType(UserDataTypeEnum.WITHHOLD_CONTRACT_SIGN.getValue());
        dataStatusDTO.setDataStatus(dataStatusEnum.getStatus());
        dataStatusDTO.setAuthTime(now);
        dataStatusDTO.setCreateTime(now);
        userStatusDubboService.saveDataStatusByUserIdAndType(dataStatusDTO);
    }

}
